package com.xy.xylive.common;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import lombok.extern.slf4j.Slf4j;

/**
 * RSA签名工具类
 */
@Component
@Slf4j
public class SignatureUtil {
    @Value("${crypto.sign-public-key}")
    private String signPublicKey;

    private Sign sign;

    /**
     * 初始化签名工具
     */
    @PostConstruct
    public void init() {
        sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, signPublicKey);
    }

    /**
     * 验证签名
     * @param params 请求参数
     * @param timestamp 时间戳
     * @param csign 客户端待验证签名
     * @return 验证结果
     */
    public boolean verify(Map<String, String> params, String timestamp, String csign) {
        if (StrUtil.isEmpty(timestamp) || StrUtil.isEmpty(csign)) {
            return false;
        }
        // 构建待验证的字符串
        Map<String, String> sortedParams = new TreeMap<>(params);
        StringBuilder sb = new StringBuilder();        
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            if (StrUtil.isNotEmpty(entry.getValue())) {
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        sb.append("timestamp=").append(timestamp);
        String content = sb.toString();
        log.info("signContent: " + content);

        try {
            // 解码Base64签名为字节数组
            byte[] signBytes = Base64.decode(csign);
            // 使用公钥验证签名
            return sign.verify(content.getBytes(StandardCharsets.UTF_8), signBytes);
        } catch (Exception e) {
            log.error("签名验证失败", e);
            return false;
        }
    }
}